import { useEffect, useRef, useState, useCallback } from 'react';
import * as THREE from 'three';

export const loadUrl = (url: string): string => {
  const newUrl = url.slice(2, url.length);
  return new URL(`../${newUrl}`, import.meta.url).href;
}

// 节流
export const useThrottle = <A extends any[], R>(fn: (...args: A) => R, delay: number, dep = []) => {
  const { current } = useRef<{
    fn: (...args: A) => R,
    timer: NodeJS.Timeout | null
  }>({ fn, timer: null });
  useEffect(function () {
    current.fn = fn;
  }, [fn]);
  return useCallback(function f(...args: A) {
    if (!current.timer) {
      current.timer = setTimeout(() => {
        current.timer = null;
      }, delay);
      current.fn(...args);
    }
  }, dep);
}


// 防抖
export const useDebounce = <A extends any[], R>(fn: (...args: A) => R, delay: number, dep = []) => {
  const { current } = useRef<{
    fn: (...args: A) => R,
    timer: NodeJS.Timeout | null
  }>({ fn, timer: null });
  useEffect(function () {
    current.fn = fn;
  }, [fn]);

  return useCallback(function f(...args:A) {
    if (current.timer) {
      clearTimeout(current.timer);
    }
    current.timer = setTimeout(() => {
      current.fn(...args);
    }, delay);
  }, dep)
}

// 防抖
export const debounce = function <A extends any[], R>(fn: (...args: A) => R, delay: number = 1000): (...args: A) => void {
  let timer: NodeJS.Timeout | null = null;
  return function (this: void, ...args: A): void {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      fn.apply(this, args);
    }, delay);
  }; 
};

// 节流
export const throttle = function <A extends any[], R>(fn: (...args: A) => R, delay: number = 1000): (...args: A) => void {
  let flag: boolean = true;
  return function (this: void, ...args: A): void {
    if (!flag) return;
    flag = false;
    setTimeout(() => {
      fn.apply(this, args);
      flag = true;
    }, delay);
  };
}






